package homework1_array.alg_3;

public class ArrayHomework {

    public static void main(String[] args) {

        //todo 作业1：完成这个测试方法中的addByElementBySequence()方法
        arrayAddTest();

        // todo 作业2：完成这个测试类中的removeByElement()方法
        deleteTest();

    }

    /**
     * 在有序列表中插入元素
     */
    private static void arrayAddTest() {

        int[] arr = new int[20];
        arr[0] = 3;
        arr[1] = 4;
        arr[2] = 7;
        arr[3] = 8;
// 1.中间位置插入
        addByElementSequence(arr, 4, 6);
        printList("在有序数组的中间部分插入元素后的结果为：", arr, 5);
        //此时应输出 3 4 6 7 8

//2.尾部插入
        addByElementSequence(arr, 5, 9);
        printList("在有序数组的尾部插入元素后的结果为：", arr, 6);
        //此时应输出 3 4 6 7 8 9

//3.数组首部插入
        addByElementSequence(arr, 6, 1);
        printList("在有序数组的首部部分插入元素后的结果为：", arr, 7);
        //此时应输出：1 3 4 6 7 8 9

    }

    //todo 作业1：完成这个方法

    /**
     * @param arr     存储元素的数组
     * @param size    数组中已经存储的元素数量
     * @param element 要插入数组的新元素
     * @return
     */
    public static void addByElementSequence(int[] arr, int size, int element) {
        //假设这个之前的代码都是严谨的，只针对这次作业的目的（强迫症作祟）
        // 1.不会有这边就不做size的值判断增加
        // 2.比较原数组大小处理和arr的判空处理
        // 3.不去对数组大小（20）进行扩容

        //int[] arrTmp = new int[arr.length]; 想想不需要临时创建一个数组，先去掉，有时间再做两个数组的
        //1.首先判断值是否大于最大的,是的话直接返回(省了循环的做法)
        if (element >= arr[size - 1]) {
            arr[size] = element;
            return;
        }
        //2.1已经排除了比最大值大的情况，可直接对比
        for (int i = size - 1; i >= 0; i--) {
            if (element <= arr[i]) {
                arr[i + 1] = arr[i];
                arr[i] = element;
            }
        }

    }

    /**
     * 删除测试
     */
    private static void deleteTest() {
        int[] arr = new int[]{2, 3, 4, 9, 10, 11, 12};

//1.删除头元素
        removeByElement(arr, 7, 2);
        printList("删除头元素后的结果为：", arr, 6);
        //此时应该打印 3 4 9 10 11 12

//2. 删除尾元素
        removeByElement(arr, 6, 12);
        printList("删除尾元素的结果为：", arr, 5);
        //此时应该打印 3 4 9 10 11

//3. 删除中间元素：
        removeByElement(arr, 5, 9);
        printList("删除中间元素的结果为：", arr, 4);
        //此时应该打印 3 4 10 11
    }

    /**
     * 从数组中删除元素e
     *
     * @param arr
     * @param size 数组已经存放的元素大小
     * @param key  要删除的元素
     */
    public static void removeByElement(int[] arr, int size, int key) {
        //用临时数组拼接很好解决，不过怕考的不是这样的，试用非临时数组的方式
       /* boolean flag = false;
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i] == key) {
                flag = true; //开关启动,再遇到一样的启动也无所谓了
            }
            if (flag) {
                arr[i] = arr[i + 1];
            }
        }
        if (flag) { //没命中的情况下不可删
            arr[arr.length - 1] = 0;
        }*/


        //突然想到如果上面出现重复的可能会有问题，于是改成这种做法
        int count = 0;
        int start = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            if (arr[i] == key) {
                arr[i] = 0; //置为空
                count++; //命中加1
                if(count == 1) //第一次命中位置
                    start = i;
            }
        }
        if (count>0) { //当然，最后这个count没排上用场……还不如一开始的boolean
            for(int i=start;i < arr.length;i++) {
                for(int j=i+1;j<arr.length;j++) {
                    if(arr[j] != 0){  //发现有0就替换
                        arr[i]=arr[j];
                        arr[j]=0;
                        break;
                    }
                }
            }
        }

    }

    public static void printList(String str, int[] arr, int key) {
        //由于参数不能改，只能用0来判断
        StringBuilder sb = new StringBuilder(str);
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 0) {
                break;
            }
            sb.append(" " + arr[i]);
        }
        System.out.println(sb.toString());
    }
}
